﻿// <copyright file="WebMessageDispatcher.cs" company="Microsoft Corporation">
// Copyright (c) 2009 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2009-12-10</date>
// <summary>WebMessageDispatcher class definition</summary>

namespace Microsoft.WebAnalytics
{
    using System;
    using System.ComponentModel.Composition;
    using System.IO;
    using System.Net;
    using System.Security;

    /// <summary>
    /// A Web Message Dispatcher
    /// </summary>
    public class WebMessageDispatcher
    {
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the WebMessageDispatcher class.
        /// </summary>
        public WebMessageDispatcher()
        {
            this.UseWebClient = false;
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets a value indicating whether to use the WebClient instead of the WebRequest
        /// </summary>
        public bool UseWebClient { get; set; }
        #endregion

        #region Methods

        /// <summary>
        /// Dispatch a web message using the Http Client
        /// </summary>
        /// <param name="message">a web message</param>
        [Export]
        public void Dispatch(WebMessage message)
        {
            if (this.UseWebClient)
            {
                DispatchWithWebClient(message);
            }
            else
            {
                DispatchWithWebRequest(message);
            }
        }
        #endregion

        #region Implementation

        /// <summary>
        /// Dispatch the message with a WebRequest
        /// </summary>
        /// <param name="message">the web message</param>
        private static void DispatchWithWebRequest(WebMessage message)
        {
            var request = WebRequest.Create(message.Address);

            request.Method = message.Method;

            if (!string.IsNullOrEmpty(message.ContentType))
            {
                request.ContentType = message.ContentType;
            }

            if (string.IsNullOrEmpty(message.Content))
            {
                request.BeginGetRequestStream(
                    new AsyncCallback(delegate(IAsyncResult result)
                    {
                        using (var stream = request.EndGetRequestStream(result))
                        {
                            using (var writer = new StreamWriter(stream))
                            {
                                writer.Write(message.Content);

                                writer.Flush();
                            }

                            request.BeginGetResponse(
                                new AsyncCallback(delegate(IAsyncResult asyncResult)
                                {
                                    request.EndGetResponse(asyncResult);
                                }), 
                                null);
                        }
                    }), 
                    null);
            }
            else
            {
                request.BeginGetResponse(
                    new AsyncCallback(delegate(IAsyncResult asyncResult)
                    {
                        try
                        {
                            request.EndGetResponse(asyncResult);
                        }
                        catch (SecurityException se)
                        {
                            System.Diagnostics.Debug.WriteLine(
                                Properties.Resources.WebMessageDispatcherSecurityError, 
                                se.Message);
                        }
                    }), 
                    null);
            }
        }

        /// <summary>
        /// Dispatch the message with a WebClient
        /// </summary>
        /// <param name="message">the web message</param>
#if SILVERLIGHT
        private static void DispatchWithWebClient(WebMessage message)
        {
            WebClient client = new WebClient();

            Dispatch(message, client);
        }
#else
        private static void DispatchWithWebClient(WebMessage message)
        {
            using (WebClient client = new WebClient())
            {
                Dispatch(message, client);
            }
        }
#endif
        /// <summary>
        /// Dispatch a web message
        /// </summary>
        /// <param name="message">the web message</param>
        /// <param name="client">the web client</param>
        private static void Dispatch(WebMessage message, WebClient client)
        {
            if (string.IsNullOrEmpty(message.Content))
            {
                client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(delegate(object sender, DownloadStringCompletedEventArgs args)
                {
                });

                client.DownloadStringAsync(message.Address);
            }
            else
            {
                client.UploadStringCompleted += new UploadStringCompletedEventHandler(delegate(object sender, UploadStringCompletedEventArgs args)
                {
                });

                client.UploadStringAsync(message.Address, message.Method, message.Content);
            }
        }
        #endregion
    }
}
